package server.connector;

import server.connector.http.HttpRequestImpl;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.io.InputStream;
/*
封装输入流,至多读取length个字节,当length < 0,无限制
当关闭流时,若未读够length个字节个字节会读够再关闭流
当流已将关闭时,再关闭会抛出IOException异常
 */
/*
2023/1/25 该类内容全部写完,后续直接使用,无需修改
by cyl
 */
public class RequestStream extends ServletInputStream {
    protected boolean closed = false;
    //累计读取的字节数
    protected int count = 0;
    //读取不超过length个字节,超过时read()返回-1,为负数时不限制读取量
    protected int length = -1;
    //被封装的输入流
    protected InputStream stream = null;

    public RequestStream(HttpRequestImpl request) {
        closed = false;
        count = 0;
        length = request.getContentLength();
        stream = request.getStream();
    }

    //关闭流,同时会读满length个字节
    @Override
    public void close() throws IOException {
        if (closed)
            throw new IOException("不能重复关闭流");
        if (length > 0) {
            while (count < length) {
                int c = read();
                //读到末尾
                if (c < 0)
                    break;
            }
        }
        closed = true;
    }

    //未读够返回读到的数,读够返回-1
    @Override
    public int read() throws IOException {
        if (closed)
            throw new IOException("流已经被关闭");
        //读够了
        if (length >= 0 && count >= length)
            return -1;
        int c = stream.read();
        if (c >= 0)
            count++;
        return c;
    }

    @Override
    public int read(byte[] b) throws IOException {
        return read(b, 0, b.length);
    }

    @Override
    public int read(byte b[], int off, int len) throws IOException {
        int toRead = len;
        if (length >= 0) {
            if (count >= length)
                return (-1);
            if ((count + len) > length)
                toRead = length - count;
        }
        int actuallyRead = super.read(b, off, toRead);
        return actuallyRead;

    }

    //暂不实现------------------------------------------------------------------------------
    @Override
    public boolean isFinished() {
        return false;
    }

    @Override
    public boolean isReady() {
        return false;
    }

    @Override
    public void setReadListener(ReadListener readListener) {

    }


}
